package simpleGeom;






import java.awt.geom.Line2D;
import java.util.Vector;

import processing.core.PVector;

public class HETriangle extends HEFace {
	HasPos2D center;
	HENode circleCenter;
	Rect2D bounds;
	public HasPos2D[]nodes;
	public boolean checked;
	float desiredArea;
	
	public boolean isLine(){
		return DelaunayMath.isOnline(nodes[0], nodes[1], nodes[2]);
		//return DelaunayMath.relativeCCW(nodes[0], nodes[1], nodes[2])==0;
		/*if (DelaunayMath.isOnline(nodes[0], nodes[1], nodes[2])){
			return true;
		}
		if (DelaunayMath.isOnline(nodes[1], nodes[2], nodes[0])){
			return true;
		}
		if (DelaunayMath.isOnline(nodes[2], nodes[0], nodes[1])){
			return true;
		}
		return false;*/
	}
	public Vector<HETriangle>children=new Vector<HETriangle>();
	public HasPos2D getCenter() {
		return center;
	}
	
	public void setCenter(HasPos2D center) {
		this.center = center;
	}
	public void init(){
		nodes=new HasPos2D[3];
		HEdge hEdge=getHEdge();
		nodes[0]=hEdge.getOrg();
		nodes[1]=hEdge.getNext().getOrg();
		nodes[2]=hEdge.getNext().getNext().getOrg();
		bounds=this.calculateBounds();
		
		circleCenter=new HENode(this.calcCircleCenter());
	}
	/*public boolean contains(HasPos2D p){
		if ()
	}*/
	
	public boolean isBorderTriangle(){
		for (int j=0;j<nodes.length;j++){
			HENode n=(HENode) nodes[j];
			if(n.getData()!=null)return true;
		}
		return false;
	}
	public Vector<HETriangle> collectEndNodes(){
		Vector<HETriangle>triangles=new Vector<HETriangle>();
		collectEndNodes(triangles);
		return triangles;
	}
	public void setCheckedAll(boolean value){
		this.checked=value;
		for (int i=0;i<children.size();i++){
			HETriangle tri=children.get(i);
			tri.setCheckedAll(value);
		}
	}
	public void collectEndNodes(Vector<HETriangle>triangles){
		if (checked)return;
		checked=true;
		if (this.children.size()==0){
			triangles.add(this);
			return;
		}
		else{
			for (int i=0;i<children.size();i++){
				HETriangle tri=children.get(i);
				tri.collectEndNodes(triangles);
			}
		}
	}
	

	
	public boolean contains(HasPos2D p){
		//if (!bounds.maxContains(p))return false;
		HasPos2D p1=nodes[0];
		HasPos2D p2=nodes[1];
		HasPos2D p3=nodes[2];
		if (DelaunayMath.isOnline(p1,p2,p))return true;
		if (DelaunayMath.isOnline(p2,p3,p))return true;
		if (DelaunayMath.isOnline(p3,p1,p))return true;
		
		/*if (DelaunayMath.isOnline(p1,p2,p))return true;
		if (DelaunayMath.isOnline(p2,p3,p))return true;
		if (DelaunayMath.isOnline(p3,p1,p))return true;*/
		
		if (DelaunayMath.relativeCCW(p1, p2, p) == Vec2D.CWRIGHT)
			return false;
		if (DelaunayMath.relativeCCW(p2, p3, p) == Vec2D.CWRIGHT)
			return false;
		if (DelaunayMath.relativeCCW(p3, p1, p) == Vec2D.CWRIGHT)
			return false;
		return true;
	}
	
	public Rect2D calculateBounds(){
		Bounds2D b=new Bounds2D();
		for (int i=0;i<nodes.length;i++){
			HasPos2D n=nodes[i];
			b.addPos2D(n);
		}
		return b;
	}
	@Override
	public Rect2D getBounds2D() {
		// TODO Auto-generated method stub
		return bounds;
	}
	
	public HETriangle getContainingTriangle(HasPos2D p) {
		if (children.size() == 0)
			return this;
		for (int i = 0; i < children.size(); i++) {
			HETriangle child = children.get(i);
			if (child.contains(p)) {
				return child.getContainingTriangle(p);
			}
			
		}
		return null;
	}
	
	
	public Vec2D calcCircleCenter(){
		HasPos2D a=nodes[0];
		HasPos2D b=nodes[1];
		HasPos2D c=nodes[2];
		Vec2D v1=Vec2D.sub(a, b);
		Vec2D v2=Vec2D.sub(a, c);
		v1.rot90();
		v2.rot90();
		
		/*double v1y=-a.getX()+b.getX();
		double v1x=a.getY()-b.getY();
		double v2y=-a.getX()+c.getY();
		double v2x=a.getY()-c.getY();*/

		double m1x=(a.getX()+b.getX())*0.5;
		double m1y=(a.getY()+b.getY())*0.5;
		double m2x=(a.getX()+c.getX())*0.5;
		double m2y=(a.getY()+c.getY())*0.5;

		double[]p= lineLineIntersectionVec(m1x,m1y,v1.getX(),v1.getY(),m2x,m2y,v2.getX(),v2.getY());
		if (p==null)return null;
		return new Vec2D((float)p[0],(float)p[1]);
	}
	
	public static double[] lineLineIntersectionVec(double aX, double aY,
			double v1x, double v1y, double bX, double bY, double v2x, double v2y) {
		double a1 = v1y;
		double b1 = -v1x;
		double c1 = a1 * aX + b1 * aY;
		// C = A*x1+B*y1
		double a2 = v2y;
		double b2 = -v2x;
		double c2 = a2 * bX + b2 * bY;

		double det = a1 * b2 - a2 * b1;

		if (Math.abs(det) <= 0.00000000) {
			System.out.println("parallel");
			return null;
			// Lines are parallel
		} else {
			double x = (b2 * c1 - b1 * c2) / det;
			double y = (a1 * c2 - a2 * c1) / det;
			return new double[] { x, y };
		}

	}

	public HENode getCircleCenter() {
		return circleCenter;
	}
	
}
